/**
 * 
 */
package com.dx.pf.commons.collection.queue;

import java.io.Serializable;
import java.util.concurrent.ConcurrentSkipListSet;

/** 
* @ClassName: CircleSequenceUniqueQueue 
* @Description: 元素不可重复的定长循环队列 
* @author wuzhenfang(wzfbj2008@163.com)
* @date 2016年11月4日 上午9:42:59 
* @version V1.0
*/
public class CircleSequenceUniqueQueue<T> implements Serializable {

	private static final long serialVersionUID = 6177918412672883273L;

	private ConcurrentSkipListSet<T> listSet = new ConcurrentSkipListSet<T>();
	private T[] queue;
	private int head = 0;
	private int tail = 0;
	private int resetSize = 10;//初始容量
	private int realSize = 0;// 实际容量

	// 初始的大小为10
	@SuppressWarnings("unchecked")
	public CircleSequenceUniqueQueue(int size) {
		queue = (T[]) new Object[(size <= 0) ? 10 : size];
		resetSize = (size <= 0) ? 10 : size;
	}

	/**
	 * 向尾部添加一个元素
	 * @param element
	 * @throws Exception
	 */
	public void addLast(T element) throws Exception {
		if (isSetContains(element)) {
			return;
		}
		tail = (head + realSize) % queue.length;
		queue[tail] = (T) element;
		addSet(element);
		realSize++;
	}

	/**
	 * 移出第一个元素
	 * @return int
	 * @throws Exception
	 */
	public T removeFirst() throws Exception {
		if (isEmpty()) {
			throw new Exception();
		}

		T tempLog = queue[head];
		queue[head] = null;
		head = (head + 1) % queue.length;
		realSize--;

		return tempLog;
	}

	/**
	 * 队列真实的数量
	 * @return int
	 */
	public int realSize() {
		return realSize;
	}

	/**
	 * 队列是否为空
	 * @return boolean
	 */
	public boolean isEmpty() {
		return realSize() == 0;
	}

	/**
	 * 队列是否已满
	 * @return boolean
	 */
	public boolean isFull() {
		return realSize() == queue.length;
	}

	/**
	 * 清除保存的所有数据
	 */
	@SuppressWarnings("unchecked")
	public void clear() {
		queue = (T[]) new Object[resetSize];
	}

	/**
	 * 返回指定位置的值
	 * @param index
	 * @return int
	 */
	public T get(int index) {
		if (index < 0 || index >= realSize) {
			throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + realSize);
		}
		return queue[index];
	}

	/**
	 * 获取元素在队列中的索引,找到就返回其位置，找不到就返回-1 如果key为null.则永远返回-1
	 * @param key 要查找的元素
	 * @return int
	 */
	public int indexOf(T key) {
		if (key == null) {
			return -1;
		} else {
			int index = 0;
			while (index <= realSize() - 1) {
				if (key.equals(queue[index])) {
					return index;
				}
				index++;
			}
		}
		return -1;
	}

	/**
	 * set中是否包含
	 * @param key
	 * @return
	 */
	private boolean isSetContains(T key) {
		return listSet.contains(key);
	}

	/**
	 * 添加元素之set中
	 * @param key
	 */
	private void addSet(T key) {
		if (realSize >= queue.length) {
			listSet.pollLast();
		}
		listSet.add(key);
	}
}
